import json
import requests
from dotenv import load_dotenv
import os

load_dotenv()

# 重定向URL常量
REDIRECT_URI = "https://open.feishu.cn/api-explorer/loading"

def get_user_access_token(authorization_code, redirect_uri=None):
    """
    使用授权码获取 user_access_token
    
    Args:
        authorization_code (str): 从授权流程获取的授权码
        redirect_uri (str, optional): 重定向URI，网页应用必填
    
    Returns:
        dict: 包含 access_token、refresh_token 等信息的响应
    """
    
    # 从环境变量获取应用凭证
    client_id = os.getenv("FEISHU_APP_ID")
    client_secret = os.getenv("FEISHU_APP_SECRET")
    
    if not client_id or not client_secret:
        raise ValueError("请在 .env 文件中配置 FEISHU_APP_ID 和 FEISHU_APP_SECRET")

    # 如果没有提供redirect_uri，使用默认值
    if redirect_uri is None:
        redirect_uri = REDIRECT_URI

    # 构造请求体
    data = {
        "grant_type": "authorization_code",
        "client_id": client_id,
        "client_secret": client_secret,
        "code": authorization_code,
        "redirect_uri": redirect_uri
    }
    
    # 发起请求
    url = "https://open.feishu.cn/open-apis/authen/v2/oauth/token"
    headers = {
        "Content-Type": "application/json; charset=utf-8"
    }
    
    try:
        response = requests.post(url, json=data, headers=headers)
        response.raise_for_status()
        
        result = response.json()
        
        # 检查响应是否成功
        if result.get("code") == 0:
            print("✅ 成功获取 user_access_token")
            print(f"Access Token: {result.get('access_token')[:50]}...")
            print(f"Token 类型: {result.get('token_type')}")
            print(f"有效期: {result.get('expires_in')} 秒")
            print(f"权限范围: {result.get('scope')}")
            
            if result.get('refresh_token'):
                print(f"Refresh Token: {result.get('refresh_token')[:50]}...")
                print(f"Refresh Token 有效期: {result.get('refresh_token_expires_in')} 秒")
            
            return result
        else:
            print(f"❌ 请求失败: {result.get('error')}")
            print(f"错误描述: {result.get('error_description')}")
            print(f"错误码: {result.get('code')}")
            return result
            
    except requests.exceptions.RequestException as e:
        print(f"❌ 网络请求失败: {e}")
        return None
    except json.JSONDecodeError as e:
        print(f"❌ JSON 解析失败: {e}")
        return None

def save_tokens_to_env(token_response):
    """
    将获取到的 token 保存到环境变量文件
    快速失败：任何异常情况都会立即抛出错误
    
    Args:
        token_response (dict): 包含 token 信息的响应
    
    Raises:
        ValueError: 当响应格式无效时
        KeyError: 当必需字段缺失时
        IOError: 当文件操作失败时
    """
    # 严格验证响应格式
    if not token_response:
        raise ValueError("Token 响应为空")
    
    if token_response.get("code") != 0:
        error_msg = token_response.get("msg", "未知错误")
        raise ValueError(f"API 返回错误: {error_msg}")
    
    # 必需字段检查 - 没有就直接报错
    access_token = token_response["access_token"]  # 直接用[]，缺失就抛KeyError
    expires_in = token_response["expires_in"]      # 同样直接要求存在
    
    # 可选字段
    refresh_token = token_response.get("refresh_token")
    refresh_token_expires_in = token_response.get("refresh_token_expires_in")
    scope_str = token_response.get("scope")
    
    # 构建环境变量字典
    env_vars = {
        "FEISHU_USER_ACCESS_TOKEN": access_token,
        "FEISHU_USER_ACCESS_TOKEN_EXPIRES_IN": str(expires_in)
    }
    
    # 只有真正存在的可选字段才添加
    if refresh_token:
        env_vars["FEISHU_REFRESH_TOKEN"] = refresh_token
    if refresh_token_expires_in is not None:
        env_vars["FEISHU_REFRESH_TOKEN_EXPIRES_IN"] = str(refresh_token_expires_in)
    if scope_str:
        env_vars["FEISHU_USER_ACCESS_TOKEN_SCOPE"] = scope_str
    
    # 文件操作 - 任何IO错误都会自然抛出
    env_path = ".env"
    env_lines = []
    
    if os.path.exists(env_path):
        with open(env_path, 'r', encoding='utf-8') as f:
            env_lines = f.readlines()
    
    # 更新环境变量
    for var_name, var_value in env_vars.items():
        updated = False
        for i, line in enumerate(env_lines):
            if line.startswith(f"{var_name}="):
                env_lines[i] = f"{var_name}={var_value}\n"
                updated = True
                break
        
        if not updated:
            env_lines.append(f"{var_name}={var_value}\n")
    
    # 写回文件
    with open(env_path, 'w', encoding='utf-8') as f:
        f.writelines(env_lines)
    
    print(f"✅ 已保存 {len(env_vars)} 个环境变量到 .env 文件")
    print(f"ℹ️  保存的字段: {', '.join(env_vars.keys())}")

def main():
    """
    主函数 - 演示如何使用
    """
    print("=== 飞书 OAuth 获取 user_access_token ===")
    print(f"使用重定向URL: {REDIRECT_URI}")
    print()
    
    # 这里需要用户手动输入授权码
    # 在实际应用中，授权码会通过回调 URL 自动获取
    authorization_code = input("请输入授权码 (authorization code): ").strip()
    
    if not authorization_code:
        print("❌ 授权码不能为空")
        return

    # 获取 user_access_token
    result = get_user_access_token(authorization_code)
    
    if result and result.get("code") == 0:
        # 询问是否保存到 .env 文件
        save_choice = input("\n是否将 token 保存到 .env 文件? (y/n): ").strip().lower()
        if save_choice == 'y':
            save_tokens_to_env(result)

if __name__ == "__main__":
    main()